package com.cdtu.outtake.service.impl;

import com.alibaba.fastjson.JSON;
import com.cdtu.outtake.comopnen.ShopOfCartComponent;
import com.cdtu.outtake.domain.CartItem;
import com.cdtu.outtake.domain.Product;
import com.cdtu.outtake.domain.ShopOfCart;
import com.cdtu.outtake.controller.vo.UpdateCartVO;
import com.cdtu.outtake.domain.Cart;
import com.cdtu.outtake.dto.ShopDto;
import com.cdtu.outtake.service.ICartService;
import com.cdtu.outtake.service.IProductService;
import com.cdtu.outtake.service.IShopService;
import com.cdtu.outtake.service.IUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author : shl
 * @Date 2024/3/8 22:55
 */
@Service
@RequiredArgsConstructor
public class CartServiceImpl implements ICartService {

    private final StringRedisTemplate redisTemplate;
    private final IUserService userService;
    private final IShopService shopService;
    private final IProductService productService;
    private final ShopOfCartComponent shopOfCartComponent;
    @Value("${redis.data-path.cart:out-take:cart:}")
    private String cartPath;

    @Override
    public ShopOfCart getShopOfCart(Long shopId) {
        List<ShopOfCart> shopOfCarts = Optional.ofNullable(JSON.parseObject(redisTemplate.opsForValue().get(cartPath + userService.getMyUserId()), Cart.class))
                .map(Cart::getShops)
                .orElse(null);
        if (shopOfCarts == null || shopOfCarts.isEmpty()) {//TODO 修改获取指定店铺购物车判断条件
            return null;
        }
        return shopOfCarts.stream()
                .filter(shopOfCart -> shopId.equals(shopOfCart.getShopId()))
                .findFirst()
                .orElse(null);
    }

    @Override
    public ShopOfCart updateCartData(UpdateCartVO updateCartVO) {
        Long userId = userService.getMyUserId();
        Cart cart = JSON.parseObject(redisTemplate.opsForValue().get(cartPath + userId), Cart.class);
        //判断该用户有没有购物车
        if (cart == null) {
            //没有购物车就先创建购物车
            cart = new Cart(userId, new ArrayList<>());
        }
        Long shopId = updateCartVO.getShopId();
        ShopOfCart shop = cart.getShops().stream()
                .collect(Collectors.toMap(ShopOfCart::getShopId, Function.identity())).getOrDefault(shopId, null);
        //判断购物车内有没有指定的商家
        if (shop == null) {
            //如果没有指定商家，先创建该商家的信息
            ShopDto shopDto = shopService.getShopDetailById(shopId).getShop();
            Double moa = shopDto.getMoa();
            shop = new ShopOfCart(shopId, shopDto.getName(), new ArrayList<>(), 0, moa, 0d, 0d);
            cart.getShops().add(shop);
        }
        Map<Long, CartItem> itemMap = shop.getCartItems().stream()
                .collect(Collectors.toMap(CartItem::getProductId, Function.identity()));
        //判断有没有加购过指定商品
        Long productId = updateCartVO.getProductId();
        if (!itemMap.containsKey(productId)) {
            //如果没有指定的商品,就进行添加操作
            Product product = productService.getProductById(productId);
            CartItem cartItem = new CartItem(productId, product.getName(), product.getHeft(), updateCartVO.getNumber(), product.getPrice(), product.getPackagePrice(), product.getPicture());
            shop.getCartItems().add(cartItem);
        } else {
            //有指定商品，进行修改操作
            CartItem cartItem = itemMap.get(productId);
            cartItem.setNumber(updateCartVO.getNumber());
        }
        shopOfCartComponent.syncData(shop);
        redisTemplate.opsForValue().set(cartPath + userId, JSON.toJSONString(cart));
        return shop;
    }

    @Override
    public void clearCartOfShop(Long shopId) {
        Long userId = userService.getMyUserId();
        Cart cart = JSON.parseObject(redisTemplate.opsForValue().get(cartPath + userId), Cart.class);
        if (cart == null || cart.getShops() == null) {
            return;
        }
        List<ShopOfCart> shops = cart.getShops();
        List<ShopOfCart> newShops = shops.stream().filter(shop -> !shop.getShopId().equals(shopId)).collect(Collectors.toList());
        cart.setShops(newShops);
        redisTemplate.opsForValue().set(cartPath + userId, JSON.toJSONString(cart));
    }
}
